package com.easytouch.vmhdl.activity;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.baidu.bpit.facepay.FacePayCallback;
import com.baidu.bpit.facepay.FacePayHelper;
import com.baidu.bpit.facepay.OrderInfo;
import com.baidu.idl.face.platform.FaceStatusEnum;
import com.baidu.idl.face.platform.utils.APIUtils;
import com.baidu.idl.face.platform.utils.CameraPreviewUtils;
import com.easytouch.vmhdl.R;
import com.easytouch.vmhdl.animation.FramesAnimation;
import com.easytouch.vmhdl.utils.FaceSDKResSettings;

import java.text.DecimalFormat;

public class FacePayActivity extends Activity implements
        Camera.ErrorCallback,
        Camera.PreviewCallback,
        SurfaceHolder.Callback {

    private static final String TAG = FacePayActivity.class.getSimpleName();

    private static final int RESULT_SHOW_TIME = 4000;

    private FacePayHelper mFacePayHelper;


//    private Button sound_btn;
//    private boolean sound = true;

    // View
    private Button mCloseView;
    private SurfaceView mSurfaceView;

    // 识别中View
    private LinearLayout mDetectingLayout;
    private ImageView mFaceOverlayView;
    private TextView mAmountView;
    private SurfaceView mScanView;
    private TextView mTipsView;

    // 支付中View
    private RelativeLayout mPayingLayout;
    private ImageView mPayingImgView;
    private FramesAnimation mPayingAnimation;
    private FramesAnimation mPaySuccessAnimation;
    private FramesAnimation mPayFailAnimation;
    private LinearLayout paySuccessNameAmountLayout;
    private LinearLayout paySuccessNameLayout;
    private TextView payStatusIngTextview;
    private TextView payStatusSuccessTextview;
    private TextView payStatusFailTextview;
    private TextView payMessageFailTextview;
    private TextView mSuccessNameTextView;
    private TextView mSuccessAmountTextView;

    private SurfaceHolder mSurfaceHolder;

    // 相机
    private Camera mCamera;
    private Camera.Parameters mCameraParam;
    private int mCameraId;
    private int mPreviewWidth;
    private int mPreviewHeight;
    private int mPreviewDegree;

    private DecimalFormat decimalFormat;

    // 状态标识
    protected boolean mIsCreateSurface = false;

    // 显示Size
    private Rect mPreviewRect = new Rect();
    private Rect mDetectRect = new Rect();
    private int mDisplayWidth = 0;
    private int mDisplayHeight = 0;

    private Handler mHandler = new Handler();
    private Runnable closeRunnable = new Runnable() {
        @Override
        public void run() {
            finish();
        }
    };
    private Animation mStatusInAnimation;
    private Animation mStatusOutAnimation;
    private Animation mMessageInAnimation;
    private String passId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_face_pay);

        FaceSDKResSettings.initializeResId();

        mFacePayHelper = new FacePayHelper(this);

        initView();

        mFacePayHelper.setDetectSoundEnable(true);

        final OrderInfo orderInfo = new OrderInfo();
        Intent intent = getIntent();
        orderIdConfig(orderInfo);
//        orderInfo.accessKey = intent.getStringExtra("accessKey");
//        orderInfo.serverSignTime = TextUtils.isEmpty(intent.getStringExtra("serverSignTime")) ? 0 : Long.valueOf(intent.getStringExtra("serverSignTime"));
//        orderInfo.serverNonce = TextUtils.isEmpty(intent.getStringExtra("serverNonce")) ? 0 : Integer.valueOf(intent.getStringExtra("serverNonce"));
//        orderInfo.serverSign = intent.getStringExtra("serverSign");
//        passId = intent.getStringExtra("passId");
//        orderInfo.passId = passId;
//        orderInfo.merchantId = TextUtils.isEmpty(intent.getStringExtra("merchantId")) ? 0 : Long.valueOf(intent.getStringExtra("merchantId"));
//        orderInfo.orderCreateTime = TextUtils.isEmpty(intent.getStringExtra("orderCreateTime")) ? 0 : Long.valueOf(intent.getStringExtra("orderCreateTime"));
//        orderInfo.orderId = intent.getStringExtra("orderId");
//        orderInfo.goodsName = intent.getStringExtra("goodsName");
//        orderInfo.goodsDesc = intent.getStringExtra("goodsDesc");
//        orderInfo.goodsUrl = intent.getStringExtra("goodsUrl");
//        orderInfo.unitAmount = TextUtils.isEmpty(intent.getStringExtra("unitAmount")) ? 0 : Long.valueOf(intent.getStringExtra("unitAmount"));
//        orderInfo.unitCount = TextUtils.isEmpty(intent.getStringExtra("unitCount")) ? 0 : Long.valueOf(intent.getStringExtra("unitCount"));
//        orderInfo.transportAmount = TextUtils.isEmpty(intent.getStringExtra("transportAmount")) ? 0 : Long.valueOf(intent.getStringExtra("transportAmount"));
//        orderInfo.totalAmount = TextUtils.isEmpty(intent.getStringExtra("totalAmount")) ? 0 : Long.valueOf(intent.getStringExtra("totalAmount"));
//        orderInfo.pageUrl = intent.getStringExtra("pageUrl");
//        orderInfo.returnUrl = intent.getStringExtra("returnUrl");
//        orderInfo.buyerSpUsername = intent.getStringExtra("buyerSpUsername");
//        orderInfo.expireTime = TextUtils.isEmpty(intent.getStringExtra("expireTime")) ? 0 : Long.valueOf(intent.getStringExtra("expireTime"));
//        orderInfo.extra = intent.getStringExtra("extra");
//        orderInfo.spPassThrough = intent.getStringExtra("spPassThrough");
//        orderInfo.profitSolution = intent.getStringExtra("profitSolution");

        decimalFormat = new DecimalFormat("0.00");

        if (orderInfo.totalAmount >= 0) {
            mAmountView.setText("待支付金额: " + decimalFormat.format(orderInfo.totalAmount * 1.0d / 100) + "元");
        }

        mFacePayHelper.pay(orderInfo, new FacePayCallback() {
            @Override
            public void onFaceDetectTips(FaceStatusEnum status, String message) {
                mTipsView.setText(message);
            }

            @Override
            public void onPaying() {

                Log.e(TAG, "onPaying");

                mCloseView.setVisibility(View.GONE);

                mDetectingLayout.setVisibility(View.GONE);
                mScanView.setVisibility(View.GONE);
                mPayingLayout.setVisibility(View.VISIBLE);
//                mPayingImgView.setBackgroundDrawable(mPayingAnimation);
                payStatusIngTextview.setVisibility(View.VISIBLE);
                mPayingAnimation.start();
            }

            @Override
            public void onPaySuccess(String name) {

//                Log.e(TAG, "onPaySuccess," + name);

                mCloseView.setVisibility(View.GONE);

                mHandler.postDelayed(closeRunnable, RESULT_SHOW_TIME);

                if (TextUtils.isEmpty(name)) {
                    paySuccessNameLayout.setVisibility(View.GONE);
                } else {
                    paySuccessNameLayout.setVisibility(View.VISIBLE);
                    mSuccessNameTextView.setText(name);
                }

                if (orderInfo.totalAmount >= 0) {
                    mSuccessAmountTextView.setText(decimalFormat.format(orderInfo.totalAmount * 1.0d / 100));
                } else {
                    mSuccessAmountTextView.setText("0");
                }

                mPayingAnimation.stop();
//                mPayingImgView.setBackgroundDrawable(mPaySuccessAnimation);
                mPaySuccessAnimation.start();
                paySuccessNameAmountLayout.setVisibility(View.VISIBLE);
                paySuccessNameAmountLayout.startAnimation(mMessageInAnimation);
                payStatusIngTextview.startAnimation(mStatusOutAnimation);
                payStatusSuccessTextview.setVisibility(View.VISIBLE);
                payStatusSuccessTextview.startAnimation(mStatusInAnimation);

                mDetectingLayout.setVisibility(View.GONE);
                mScanView.setVisibility(View.GONE);
                mPayingLayout.setVisibility(View.VISIBLE);
            }

            @Override
            public void onPayError(String errCode, String title, String message) {
                Log.e(TAG, "onPayError," + errCode + "," + title + "," + message);

                mCloseView.setVisibility(View.GONE);

                mHandler.postDelayed(closeRunnable, RESULT_SHOW_TIME);

                payStatusFailTextview.setText(title);
                payMessageFailTextview.setText(message);

                mPayingAnimation.stop();
//                mPayingImgView.setBackgroundDrawable(mPayFailAnimation);
                mPayFailAnimation.start();
                payStatusIngTextview.startAnimation(mStatusOutAnimation);
                payStatusFailTextview.setVisibility(View.VISIBLE);
                payStatusFailTextview.startAnimation(mStatusInAnimation);
                payMessageFailTextview.setVisibility(View.VISIBLE);
                payMessageFailTextview.startAnimation(mMessageInAnimation);

                mDetectingLayout.setVisibility(View.GONE);
                mScanView.setVisibility(View.GONE);
                mPayingLayout.setVisibility(View.VISIBLE);

            }
        });

    }

    private void orderIdConfig(OrderInfo orderInfo) {
        orderInfo.accessKey = "fengguo_facepay_online"; //测试环境 test 正式环境  ak sk fengguo_facepay_online
        orderInfo.serverSignTime = 1511160254;
        orderInfo.serverNonce = 2089;
        orderInfo.serverSign = "3eede6d900c8697b8d173268b9612db3";//正式环境 3eede6d900c8697b8d173268b9612db3  测试环境f7efb30a166b3c42ea6e4c4db5c62f19
        orderInfo.passId = passId;
        orderInfo.merchantId = 2; //正式环境 2,测试环境 6
        orderInfo.orderCreateTime = 1511160043000L;
        orderInfo.orderId = SystemClock.currentThreadTimeMillis()+"";
        orderInfo.goodsName = "32132";
        orderInfo.goodsDesc = "fg";
        orderInfo.goodsUrl = "http://cp01-rdqa-dev340-wangying31.epc.baidu.com:8080/pay/notify/facebpit";
        orderInfo.unitAmount = 1;
        orderInfo.unitCount = 1;
        orderInfo.transportAmount = 0;
//        mLogger.i("tatalAmount 01:" + totalAmount);
        orderInfo.totalAmount =1;
//        mLogger.i("orderInfo.totalAmount:" + orderInfo.totalAmount);
        orderInfo.pageUrl = "http://db-testing-eb07.db01.baidu.com:8666/success.html";
        orderInfo.returnUrl = "http://cp01-rdqa-dev340-wangying31.epc.baidu.com:8080/pay/notify/facebpit";
        orderInfo.buyerSpUsername = "buyer_sp_username";
        //        orderInfo.expireTime = TextUtils.isEmpty(intent.getStringExtra("expireTime"))
        //                ? 0 : Long.valueOf(intent.getStringExtra("expireTime"));
        //        orderInfo.extra = intent.getStringExtra("extra");
        //        orderInfo.spPassThrough = intent.getStringExtra("spPassThrough");
        //        orderInfo.profitSolution = intent.getStringExtra("profitSolution");
    }
    private void initView() {
        mCloseView = (Button) findViewById(R.id.port_close);
        mSurfaceView = (SurfaceView) findViewById(R.id.port_surface_view);

        mDetectingLayout = (LinearLayout) findViewById(R.id.detecting_layout);
        mScanView = (SurfaceView) findViewById(R.id.ring_view);
        mFaceOverlayView = (ImageView) findViewById(R.id.port_detect_img);
        mTipsView = (TextView) findViewById(R.id.port_tips);
        mAmountView = (TextView) findViewById(R.id.amount_taxtview);


        mPayingLayout = (RelativeLayout) findViewById(R.id.paying_layout);
        mPayingImgView = findViewById(R.id.img_status_paying);
//        mPayingAnimation = (AnimationDrawable) getResources().getDrawable(R.drawable.anim_paying);
//        mPaySuccessAnimation = (AnimationDrawable) getResources().getDrawable(R.drawable.anim_pay_success);
//        mPayFailAnimation = (AnimationDrawable) getResources().getDrawable(R.drawable.anim_pay_fail);
        mPayingAnimation = new FramesAnimation(mPayingImgView, getResources().obtainTypedArray(R.array.paying_anim), 25, false);
        mPaySuccessAnimation = new FramesAnimation(mPayingImgView, getResources().obtainTypedArray(R.array.pay_success_anim), 25, true);
        mPayFailAnimation = new FramesAnimation(mPayingImgView, getResources().obtainTypedArray(R.array.pay_fail_anim), 25, true);

        payStatusIngTextview = findViewById(R.id.pay_status_ing_textview);
        payStatusSuccessTextview = findViewById(R.id.pay_status_success_textview);
        payStatusFailTextview = findViewById(R.id.pay_status_fail_textview);
        payMessageFailTextview = findViewById(R.id.pay_fail_message_layout);
        paySuccessNameAmountLayout = findViewById(R.id.pay_success_name_amount_layout);
        paySuccessNameLayout = findViewById(R.id.pay_success_name_layout);
        mMessageInAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_message_in);
        mStatusOutAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_status_out);
        mStatusInAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_status_in);


        mSuccessNameTextView = (TextView) findViewById(R.id.success_name_textview);
        mSuccessAmountTextView = (TextView) findViewById(R.id.success_amount_textview);

//        mCloseView.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
//                if (mFacePayHelper == null) {
//                    finish();
//                    return;
//                }
//        mFacePayHelper.cancle(new FacePayCancelCallback() {
//            @Override
//            public void onCancelSuccess() {
//                finish();
//                Toast.makeText(FacePayActivity.this, "取消订单成功", Toast.LENGTH_SHORT).show();
//            }
//
//            @Override
//            public void onCancelFail(int errCode) {
//                if (errCode == LocalErrCode.CANCEL_PAYING) {
//                    Toast.makeText(FacePayActivity.this, "取消订单失败，请等待支付结果", Toast.LENGTH_SHORT).show();
//                } else if (errCode == LocalErrCode.CANCEL_COMPLETED) {
//                    Toast.makeText(FacePayActivity.this, "取消订单失败，订单已完成", Toast.LENGTH_SHORT).show();
//
//                }
//            }
//        });
//            }
//        });

        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.setSizeFromLayout();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    }

    @Override
    public void onResume() {
        super.onResume();
        startPreview();
    }

    @Override
    public void onPause() {
        super.onPause();
        stopPreview();
    }

    @Override
    public void onStop() {
        super.onStop();
        stopPreview();
    }

    @Override
    public void finish() {
        super.finish();
        destroy();
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        mIsCreateSurface = true;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (holder.getSurface() == null) {
            return;
        }

        new Handler().postDelayed(new Runnable() {
            public void run() {
                startPreview();
            }
        }, 500);

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        mIsCreateSurface = false;
    }

    protected void startPreview() {
        if (mSurfaceView != null && mSurfaceView.getHolder() != null) {
            mSurfaceHolder = mSurfaceView.getHolder();
            mSurfaceHolder.addCallback(this);
        }

        if (mCamera == null)
            mCamera = open();
        if (mCameraParam == null) {
            mCameraParam = mCamera.getParameters();
        }

//        mCameraParam.setPictureFormat(PixelFormat.JPEG);
        int degree = displayOrientation(this);


        mCamera.setDisplayOrientation(degree);
        // 设置后无效，camera.setDisplayOrientation方法有效
        mCameraParam.set("rotation", degree);

//        mPreviewDegree = degree == 0 ? 360 : degree;
        mPreviewDegree = degree;

        DisplayMetrics dm = new DisplayMetrics();
        Display display = getWindowManager().getDefaultDisplay();
        display.getMetrics(dm);
        mDisplayWidth = dm.widthPixels;
        mDisplayHeight = dm.heightPixels;

        Point point = CameraPreviewUtils.getBestPreview(mCameraParam, new Point(mDisplayWidth, mDisplayHeight));
//        Point point = new Point(320, 240);

        mPreviewWidth = point.x;
        mPreviewHeight = point.y;

        float ratioX;
        float ratioY;

        mPreviewRect.set(0, 0, mPreviewHeight, mPreviewWidth);

        if (degree == 90 || degree == 270) {
            ratioX = (mPreviewHeight * 1f) / (mDisplayWidth * 1f);
            ratioY = (mPreviewWidth * 1f) / (mDisplayHeight * 1f);
        } else {
            ratioX = (mPreviewWidth * 1f) / (mDisplayWidth * 1f);
            ratioY = (mPreviewHeight * 1f) / (mDisplayHeight * 1f);
        }

        mFaceOverlayView.getGlobalVisibleRect(mDetectRect);
        mDetectRect = new Rect(
                (int) (mDetectRect.left * ratioX),
                (int) (mDetectRect.top * ratioY),
                (int) (mDetectRect.right * ratioX),
                (int) (mDetectRect.bottom * ratioY));

        mCameraParam.setPreviewSize(mPreviewWidth, mPreviewHeight);
        mCamera.setParameters(mCameraParam);

        mFacePayHelper.setDetectConfig(mPreviewDegree, mPreviewRect, mDetectRect);

        Log.e(TAG, "_________________________________________________________");
        Log.e(TAG, "mPreviewDegree:" + mPreviewDegree);
        Log.e(TAG, "mPreviewRect:" + mPreviewRect.left + ", "
                + mPreviewRect.top + ", "
                + mPreviewRect.right + ", "
                + mPreviewRect.bottom + ", ");
        Log.e(TAG, "mDetectRect:" + mDetectRect.left + ", "
                + mDetectRect.top + ", "
                + mDetectRect.right + ", "
                + mDetectRect.bottom + ", ");
        Log.e(TAG, "_________________________________________________________");


        try {
            mCamera.setPreviewDisplay(mSurfaceHolder);
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            mCamera.stopPreview();
            mCamera.setErrorCallback(this);
            mCamera.setPreviewCallback(this);
        } catch (Exception e) {
            try {
                mCamera.release();
            } catch (RuntimeException e2) {
                e2.printStackTrace();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            mCamera = null;
        }
        mCamera.startPreview();
    }

    private Camera open() {
        Camera camera;
        int numCameras = Camera.getNumberOfCameras();
        if (numCameras == 0) {
            return null;
        }

        int index = 0;
        while (index < numCameras) {
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            Camera.getCameraInfo(index, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                break;
            }
            index++;
        }

        if (index < numCameras) {
            camera = Camera.open(index);
            mCameraId = index;
        } else {
            camera = Camera.open(0);
            mCameraId = 0;
        }
        return camera;
    }


    private int displayOrientation(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        int rotation = windowManager.getDefaultDisplay().getRotation();
        int degrees = 0;
        if (rotation == Surface.ROTATION_0) {
            degrees = 0;

        } else if (rotation == Surface.ROTATION_90) {
            degrees = 90;

        } else if (rotation == Surface.ROTATION_180) {
            degrees = 180;

        } else if (rotation == Surface.ROTATION_270) {
            degrees = 270;

        } else {
            degrees = 0;

        }
        int result = (0 - degrees + 360) % 360;
        if (APIUtils.hasGingerbread()) {
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(mCameraId, info);
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                result = (info.orientation + degrees) % 360;
                result = (360 - result) % 360;
            } else {
                result = (info.orientation - degrees + 360) % 360;
            }
        }
        return result;
    }

    @Override
    public void onError(int i, Camera camera) {

    }


    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {

        mFacePayHelper.setDetectConfig(mPreviewDegree, mPreviewRect, mDetectRect);
        mFacePayHelper.detectData(data);

    }

    protected void stopPreview() {
        if (mCamera != null) {
            try {
                mCamera.setErrorCallback(null);
                mCamera.setPreviewCallback(null);
                mCamera.stopPreview();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    mCamera.release();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
                mCamera = null;
            }
        }
        if (mSurfaceHolder != null) {
            mSurfaceHolder.removeCallback(this);
        }
    }

    protected void destroy() {
        if (mCamera != null) {
            try {
                mCamera.setErrorCallback(null);
                mCamera.setPreviewCallback(null);
                mCamera.stopPreview();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    mCamera.release();
                } catch (RuntimeException e2) {
                    e2.printStackTrace();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
                mCamera = null;
            }
        }
    }


}
